﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.IO;
using System.Diagnostics;
using System.Linq;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PachubeDataAccess.Models;
using System.Globalization;
using System.Threading;

namespace PachubeDataAccess
{
    public class PachubeAgent
    {
        public event FeedsListReceivedHandler FeedsListReceived;
        public event FeedsListReceivedHandler SearchCompleted;

        private string _apiKey;

        public PachubeAgent(string ApiKey)
        {
            _apiKey = ApiKey;
        }

        private string BuildUrl(double latitude, double longitude, double distance)
        {
            CultureInfo ci = new CultureInfo("en-us");
            Thread.CurrentThread.CurrentCulture = ci;
            Thread.CurrentThread.CurrentUICulture = ci;

            return PachubeDataAccess.Resources.FeedsBaseUrl + "?lat=" + latitude.ToString() + "&lng=" + longitude.ToString() + "&distance=5.0&distance_unit=kms";
        }

        private string BuildUrl(string query)
        {
            return PachubeDataAccess.Resources.FeedsBaseUrl + "?q=" + query;
        }

        public void GetFeedsAroundLocation(double latitude, double longitude, double distance)
        {
            string url = BuildUrl(latitude, longitude, distance);
            GetFeeds(url, this.FeedsListReceived);
        }

        public void GetFeedsByKeyword(string query)
        {
            string url = BuildUrl(query);
            GetFeeds(url, this.SearchCompleted);
        }

        private void GetFeeds(string url, FeedsListReceivedHandler eventToFire)
        { 
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "GET";
            //req.ContentType = "application/json";
            req.Headers["X-PachubeApiKey"] = _apiKey;

            try
            {
                req.BeginGetResponse(state =>
                {
                    try { 
                        WebResponse resp = (state.AsyncState as HttpWebRequest).EndGetResponse(state);
                        using (Stream s = resp.GetResponseStream())
                        {
                            byte[] data = new byte[s.Length];
                            s.Read(data, 0, (int)s.Length);
                            string resultAsString = new string(System.Text.Encoding.UTF8.GetChars(data));
                            JObject resultAsJson = JObject.Parse(resultAsString);
                            JToken feedsAsJson = resultAsJson.SelectToken("results");
                            int itemsPerPage = (int)resultAsJson["itemsPerPage"];
                            int resultsCount = (int)resultAsJson["totalResults"];
                            var target = (itemsPerPage > resultsCount) ? resultsCount : itemsPerPage;

                            ObservableCollection<Feed> results = new ObservableCollection<Feed>();
                            for (int i = 0; i < target; i++)
                            {
                                JToken feedAsJson = feedsAsJson[i];
                                Feed f = new Feed(_apiKey);
                                f.Id = (int)feedAsJson["id"];
                                f.Title = (string)feedAsJson["title"];
                                f.Url = (string)feedAsJson["feed"];
                                f.Location = new FeedLocation();
                                try
                                {
                                    f.Location.Latitude = (double)feedAsJson["location"]["lat"];
                                    f.Location.Longitude = (double)feedAsJson["location"]["lon"];
                                    f.Location.Name = (string)feedAsJson["location"]["name"];
                                    f.Location.Domain = (string)feedAsJson["location"]["domain"];
                                    f.Location.Elevation = (string)feedAsJson["location"]["ele"];
                                    f.Location.IsFixed = ((string)feedAsJson["location"]["disposition"] == "fixed");
                                    f.Location.IsIndoor = ((string)feedAsJson["location"]["exposure"] == "fixed");
                                }
                                catch(Exception)
                                {
                                    Debug.WriteLine("could not find one or more members of the location");
                                }
                                JToken datastreamsAsJson = feedAsJson.SelectToken("datastreams");
                                if (datastreamsAsJson != null)
                                {
                                    f.DataStreams = DataStream.ParseJSON(f, datastreamsAsJson);
                                }
                                results.Add(f);
                        
                            }
                        
                            if (eventToFire != null)
                            {
                                eventToFire(this, new FeedsListReceivedEventArgs() { Feeds = results });
                            }
                        }

                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("error in PachubeAgent.cs: GetFeeds : " + ex.Message);
                    }

                }, req);

            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }   
        }

    }


    public delegate void FeedsListReceivedHandler (object sender, FeedsListReceivedEventArgs e);
    public class FeedsListReceivedEventArgs : EventArgs
    {
        public ObservableCollection<Feed> Feeds;
    }
        
}
